import React, {useRef, useState} from "react";
import ProForm, {FormInstance, ProFormText} from "@ant-design/pro-form"
import {Button, Form, Input, ModalProps} from "antd";
import {PlusOutlined} from "@ant-design/icons";
import {ModalPermission} from "@/components/Permission";
import departmentService from "@/services/department";
import userService from "@/services/user";
import roleService from "@/services/role";
import {UserDTO, UserVO} from "@/types/user";
import {OptionType} from "@/types/common";
import {arrayToTree} from "@/utils/utils";
import CustomTreeSelect from "@/components/CustomTreeSelect";
import {RuleObject, StoreValue} from "rc-field-form/lib/interface";

interface UserFormProps{
  entity?:UserVO;
  roleOptions?:OptionType[];
  departmentOptions?:OptionType[];
  onFinish?: (formData:any) => Promise<any | void>;
  /** @name 用于触发抽屉打开的 dom */
  trigger?: JSX.Element;
  /** @name 获取真正的可以获得值的 from */
  formRef?: React.MutableRefObject<(FormInstance & {
    getFieldsFormatValue?: () => any;
  }) | undefined>;
  onReset:()=>void;
  functionKey?:string;
  /** @name 打开关闭的事件 */
  onVisibleChange?: (visible: boolean) => void;
  /** @name 受控的打开关闭 */
  visible?: ModalProps['visible'];
  isModify?: boolean
}

const create= async (params:UserDTO): Promise<UserVO> => {
  const response=await userService.create(params);
  const {data}=response;
  return new Promise((resolve, reject) => {
    resolve(data);
  })
}

const modify= async (params:UserDTO): Promise<UserVO> => {
  const response=await userService.modify(params);
  const {data}=response;
  return new Promise((resolve, reject) => {
    resolve(data);
  })
}

const UserForm:React.FC<UserFormProps> = (props) =>{

  const formRef = useRef<FormInstance>();

  const onFinish=async (values:any) => {
    return new Promise<boolean|void>((resolve, reject)=>{
      if(props.onFinish){
        if(values.roleIds){
          values.roleIds=[values.roleIds];
        }else{
          values.roleIds=[];
        }
        props.onFinish(values)
          .then((data)=>{
            if(data){
              resolve(true);
              formRef.current?.resetFields();
              props.onReset();
            }else{
              reject();
            }
          });
      }
    })
  }

  const checkPassword = (rule: RuleObject, value: StoreValue, callback: (error?: string) => void): Promise<void | any> | void => {
    const password = formRef.current?.getFieldValue('password');
    return new Promise<void | any> ((resolve,reject) => {
      if (!value || value !== password) {
        reject('两次密码输入不一致');
      }else{
        resolve(value);
      }
    })
  };

  const departmentList=props.entity?.departmentList;
  const roleList=props.entity?.roleList;

  return (
    <ModalPermission
      formRef={formRef}
      functionKey={props.functionKey}
      visible={props.visible}
      onVisibleChange={props.onVisibleChange}
      trigger={props.trigger}
      onFinish={onFinish}
      initialValues={{
        id:props.entity?.id,
        name:props.entity?.name,
        username:props.entity?.username,
        mobile:props.entity?.mobile,
        email:props.entity?.email,
        roleIds:roleList&&roleList.length>0?roleList[0].id:undefined,
        // @ts-ignore
        departmentId:departmentList?departmentList[0].id:undefined,
        organizationId:props.entity?.organizationId,
      }}
    >
      <ProForm.Group>
        <ProFormText
          width="md"
          name={'username'}
          label="用户名"
          rules={[
            {required:true,message:'请输入用户名'}
          ]}
          disabled={props.isModify}
          placeholder="请输入用户名"
        />
        <ProFormText
          width="md"
          name={'name'}
          label="姓名"
          rules={[
            {required:true,message:'请输入姓名'}
          ]}
          placeholder="请输入姓名"
        />
        {!props.isModify&&(
          <>
            <ProFormText.Password
              width="md"
              name={'password'}
              label="密码"
              placeholder="请输入密码"
              rules={[
                {
                  required:true,
                  pattern: /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,16}$/,
                  message: '密码必须包含大小写字母、数字，长度为8-16位',
                }
              ]}
            />
            <ProFormText.Password
              width="md"
              name={'confirmPassword'}
              label="确认密码"
              placeholder="请确认密码"
              required={true}
              rules={[
                { validator: checkPassword },
              ]}
            />
          </>
        )}
        <ProFormText
          width="md"
          name={'email'}
          label="邮箱"
          rules={[
            {type: 'email',required:true,message:'邮箱不是一个有效的email'}
          ]}
          placeholder="请输入邮箱"
        />
        <ProFormText
          width="md"
          name={'mobile'}
          label="手机"
          rules={[
            {required:true,message:'请输入手机'}
          ]}
          placeholder="请输入手机"
        />

        <Form.Item
          className={'pro-field-md'}
          name={'departmentId'}
          label="部门"
        >
          <CustomTreeSelect list={props.departmentOptions} multiple={false}/>
        </Form.Item>
        <Form.Item
          className={'pro-field-md'}
          name={'roleIds'}
          label="角色"
        >
          <CustomTreeSelect list={props.roleOptions} multiple={false}/>
        </Form.Item>
        <Form.Item name="id">
          <Input type={'hidden'} />
        </Form.Item>
        <Form.Item name="organizationId">
          <Input type={'hidden'} />
        </Form.Item>
      </ProForm.Group>
    </ModalPermission>
  )
}

export const UserCreateForm:React.FC<UserFormProps> = (props) =>{
  const formRef = useRef<FormInstance>();

  const [departmentOptions,setDepartmentOptions] = useState<OptionType[]>([]);
  const [roleOptions,setRoleOptions] = useState<OptionType[]>([]);

  const onClick=async ()=>{
    const {data:departmentList}=await departmentService.queryList({
      organizationId:props.entity?.organizationId,
    });
    const {data:roleList}=await roleService.queryList({
      organizationId:props.entity?.organizationId,
    });
    setDepartmentOptions(arrayToTree(departmentList));
    setRoleOptions(arrayToTree(roleList));

    const roles=props.entity?.roleList;

    formRef.current?.setFieldsValue({
      id:props.entity?.id,
      name:props.entity?.name,
      username:props.entity?.username,
      mobile:props.entity?.mobile,
      email:props.entity?.email,
      roleIds:roles&&roles.length>0?roles[0].id:undefined,
      // @ts-ignore
      organizationId:props.entity?.organizationId,
    })
  }

  return (
    <UserForm
      {...props}
      roleOptions={roleOptions}
      departmentOptions={departmentOptions}
      formRef={formRef}
      onFinish={create}
      isModify={false}
      trigger={
        <Button type="primary" onClick={onClick}>
          <PlusOutlined />
          新建用户
        </Button>
      }
    />
  )
}

export const UserModifyForm:React.FC<UserFormProps> = (props) =>{
  const formRef = useRef<FormInstance>();

  const [departmentOptions,setDepartmentOptions] = useState<OptionType[]>([]);
  const [roleOptions,setRoleOptions] = useState<OptionType[]>([]);

  const onVisibleChange=async (visible: boolean)=>{
    if(visible){
      const {data:departmentList}=await departmentService.queryList({
        organizationId:props.entity?.organizationId,
      });
      const {data:roleList}=await roleService.queryList({
        organizationId:props.entity?.organizationId,
      });
      setDepartmentOptions(arrayToTree(departmentList));
      setRoleOptions(arrayToTree(roleList));

      const roles=props.entity?.roleList;

      formRef.current?.setFieldsValue({
        id:props.entity?.id,
        name:props.entity?.name,
        username:props.entity?.username,
        mobile:props.entity?.mobile,
        email:props.entity?.email,
        roleIds:roles&&roles.length>0?roles[0].id:undefined,
        // @ts-ignore
        departmentId:props.entity?.departmentList[0].id,
        organizationId:props.entity?.organizationId,
      })
    }
    if(props.onVisibleChange && !visible){
      props.onVisibleChange(visible);
    }
  }

  return (
    <UserForm
      {...props}
      roleOptions={roleOptions}
      departmentOptions={departmentOptions}
      formRef={formRef}
      isModify={true}
      onFinish={modify}
      onVisibleChange={onVisibleChange}
    />
  )
}

